package com.java.advance.custom.mybatis.excutor;

import com.java.advance.custom.mybatis.config.Configuration;
import com.java.advance.custom.mybatis.config.MapperStatement;
import com.java.advance.custom.mybatis.utils.ReflectionUtil;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by aivin on 2019/3/12.
 */
public class DefaultExcutor implements Executor {

    private Configuration configuration;

    public DefaultExcutor(Configuration configuration) {
        super();
        this.configuration = configuration;
    }

    @Override
    public <E> List<E> query(MapperStatement mapperStatement, Object parameter) {
        System.out.println(mapperStatement.getSql());
        System.out.println(mapperStatement.getResultType());

        List<E> ret = new ArrayList<E>();//定义返回的结果集
        try {
            Class.forName(configuration.getJdbcDriver());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            //获取连接，从MapperStatement中读取数据库信息
            connection = DriverManager.getConnection(configuration.getJdbcUrl(), configuration.getJdbcUsername(), configuration.getJdbcPassward());
            //创建prepareStatement，从MapperStatement中获取SQL语句
            preparedStatement = connection.prepareStatement(mapperStatement.getSql());
            //处理SQL语句中的占位符
            parameterize(preparedStatement, parameter);
            //执行查询操作，获取ResultSet
            resultSet = preparedStatement.executeQuery();
            //将结果集通过反射技术，填充到list中
            handlerResultSet(resultSet, ret, mapperStatement.getResultType());
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                resultSet.close();
                preparedStatement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return ret;
    }

    /**
     * 对prepareStatement中的占位符进行处理
     *
     * @param preparedStatement
     * @param parameter
     * @throws SQLException
     */
    private void parameterize(PreparedStatement preparedStatement, Object parameter) throws SQLException {
        if (parameter instanceof Integer) {
            preparedStatement.setInt(1, (int) parameter);
        } else if (parameter instanceof Long) {
            preparedStatement.setLong(1, (Long) parameter);
        } else if (parameter instanceof String) {
            preparedStatement.setString(1, (String) parameter);
        }
    }

    /**
     * 读取ResultSet中的数据，并转换成目标对象
     *
     * @param resultSet
     * @param ret
     * @param className
     * @param <E>
     */
    private <E> void handlerResultSet(ResultSet resultSet, List<E> ret, String className) {
        Class<E> clazz = null;
        try {
            //通过反射获取类对象
            clazz = (Class<E>) Class.forName(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {
            while (resultSet.next()) {
                // 通过反射实例化对象
                Object entity = clazz.newInstance();
                //使用反射工具将resultSet中的数据填充到entity中
                ReflectionUtil.setPropertyToBeanFromResultSet(entity, resultSet);
                //对象加入返回集合中
                ret.add((E) entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //使用JDBC链接数据库
}
